﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using WebApiDemo.Models.ApiResultModels;
using WebApiDemo.Models.Database;
using WebApiDemo.Models.RequesForms;
using WebApiDemo.Models.RequestForms;
using WebApiDemo.Models.UnionModels;

namespace WebApiDemo.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class GoodsController : ControllerBase
    {
        private readonly Store_2022Context _db;
        private readonly IMemoryCache cache;

        public GoodsController(Store_2022Context db, IMemoryCache cache)
        {
            _db = db;
            this.cache = cache;
        }

        /// <summary>
        /// 添加商品(接收数据库Model)
        /// </summary>
        [HttpPost]
        public string AddFromModel(Good good)
        {
            _db.Goods.Add(good);
            var row = _db.SaveChanges();
            if (row > 0)
                return "新增成功";
            return "新增失败";
        }

        /// <summary>
        /// 添加商品(自定义Model)
        /// </summary>
        [HttpPost]
        public string Add([FromBody] AddGoodsRF request)
        {
            _db.Goods.Add(new Good()
            {
                Name = request.Name,
                CateId = request.CateId,
                Cover = request.Cover,
                CreateTime = DateTime.Now,
                Price = request.Price,
                Stock = request.Stock,
            });
            var row = _db.SaveChanges();
            if (row > 0)
                return "新增成功";
            return "新增失败";
        }

        /// <summary>
        /// 添加商品并验证(自定义Model)
        /// </summary>
        [HttpPost]
        public string AddAndValid([FromBody] AddGoodsValidRF request)
        {
            _db.Goods.Add(new Good()
            {
                Name = request.Name,
                CateId = request.CateId,
                Cover = request.Cover,
                CreateTime = DateTime.Now,
                Price = request.Price,
                Stock = request.Stock,
            });
            var row = _db.SaveChanges();
            if (row > 0)
                return "新增成功";
            return "新增失败";
        }

        /// <summary>
        /// 添加商品(使用ParamsQuery)
        /// </summary>
        /// <param name="name">名字</param>
        /// <param name="cateId">食品id</param>
        /// <param name="cover">封面</param>
        /// <param name="price">价格</param>
        /// <param name="stock">库存</param>
        /// <returns></returns>
        [HttpPost]
        public string AddFromParams(string name, int cateId, string cover, decimal price, int stock)
        {
            _db.Goods.Add(new Good()
            {
                Name = name,
                CateId = cateId,
                Cover = cover,
                CreateTime = DateTime.Now,
                Price = price,
                Stock = stock,
            });
            var row = _db.SaveChanges();
            if (row > 0)
                return "新增成功";
            return "新增失败";
        }

        /// <summary>
        /// 更新商品(接收数据库Model)
        /// </summary>
        /// <param name="good">商品数据库Model</param>
        /// <returns></returns>
        [HttpPost]
        public string Update(Good good)
        {
            var model = _db.Goods.FirstOrDefault(x => x.Id == good.Id);
            if (model == null)
                return "数据不存在";

            model.Name = good.Name;
            model.Cover = good.Cover;
            model.CateId = good.CateId;
            model.Stock = good.Stock;
            _db.Goods.Update(model);
            var row = _db.SaveChanges();
            if (row > 0)
                return "更新成功";
            return "更新失败";
        }

        /// <summary>
        /// 删除商品
        /// </summary>
        /// <param name="goodId">商品ID</param>
        /// <returns></returns>
        [HttpPost]
        public string Delete(int goodId)
        {
            var model = _db.Goods.FirstOrDefault(x => x.Id == goodId);
            if (model == null)
                return "数据不存在";

            _db.Goods.Remove(model);
            var row = _db.SaveChanges();
            if (row > 0)
                return "删除成功";
            return "删除失败";
        }


        private static string KEY_GETALL = "control-goods-getall";
        /// <summary>
        /// 获取全部商品
        /// </summary>
        [HttpGet]
        public List<Good> GetAll()
        {
            List<Good> goods = cache.GetOrCreate(KEY_GETALL, entry =>
            {
                entry.SetSlidingExpiration(TimeSpan.FromMinutes(30));
                entry.SetAbsoluteExpiration(DateTimeOffset.Now.AddMinutes(10));
                return _db.Goods.ToList();
            });

            return goods;
        }

        /// <summary>
        /// 查询商品并返回全部查询结果(使用自定义Model, 但限定使用QueryString)
        /// </summary>
        [HttpGet]
        public List<Good> QueryAll([FromQuery] QueryGoodsRF request)
        {
            //获取商品操作
            var list = _db.Goods.AsQueryable();
            //如果查询的分类Id>0 
            if (request.CateId > 0)
                list = list.Where(x => x.CateId == request.CateId);
            //如果查询的关键字不为空
            if (!string.IsNullOrEmpty(request.Keyword))
                list = list.Where(x => x.Name.Contains(request.Keyword));
            return list.ToList();
        }

        /// <summary>
        /// 查询商品并返回全部查询结果(使用ParamsQuery)
        /// </summary>
        [HttpPost]
        public List<Good> QueryAllFromParams(string keyword, int cateId)
        {
            //获取商品操作
            var list = _db.Goods.AsQueryable();
            //如果查询的分类Id>0 
            if (cateId > 0)
                list = list.Where(x => x.CateId == cateId);
            //如果查询的关键字不为空
            if (!string.IsNullOrEmpty(keyword))
                list = list.Where(x => x.Name.Contains(keyword));
            return list.ToList();
        }

        /// <summary>
        /// 获取全部商品数据(使用ParamsQuery)
        /// </summary>
        /// <param name="keyword">关键词</param>
        /// <param name="cateId">类型Id</param>
        /// <returns></returns>
        [HttpPost]
        public List<GoodsModelUM> GetAllGoods(string keyword, int cateId)
        {
            //获取商品操作
            var goods = _db.Goods.AsQueryable();
            //如果查询的分类Id>0 
            if (cateId > 0)
                goods = goods.Where(x => x.CateId == cateId);
            //如果查询的关键字不为空
            if (!string.IsNullOrEmpty(keyword))
                goods = goods.Where(x => x.Name.Contains(keyword));

            var list = goods.Join(_db.Categories, x => x.CateId, y => y.Id, (x, y) => new GoodsModelUM
            {
                Name = x.Name,
                CateId = x.CateId,
                CategoryName = y.CateName,
                Cover = x.Cover,
                Id = x.Id,
                Price = x.Price,
                Stock = x.Stock
            }).ToList();
            return list;
        }

        /// <summary>
        /// 获取商品类型以及对应商品
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public List<CategoryAndProduct> GetAllCategoryAndProducts()
        {
            var categoryAndProducts = _db.Categories
                .Select(cate => new CategoryAndProduct
                {
                    CategoryId = cate.Id,
                    CategoryName = cate.CateName,
                    ProductList = _db.Goods
                        .Where(goods => cate.Id == goods.CateId)
                        .Select(goods => new SimpleProductUM
                        {
                            GoodsId = goods.Id,
                            Name = goods.Name,
                        }).ToList()
                }).ToList();

            return categoryAndProducts;
        }

        /// <summary>
        /// 查询商品类型并返回对应商品
        /// </summary>
        /// <param name="cateName"></param>
        /// <returns></returns>
        [HttpGet]
        public List<CategoryAndProduct> QueryAllCategoryAndProducts(string cateName)
        {
            var cacheKey = "QueryAllCategoryAndProducts_" + cateName;
            List<CategoryAndProduct> data;
            if (cache.TryGetValue<List<CategoryAndProduct>>(cacheKey, out data))
            {
                return data;
            }
            var categoryAndProducts = _db.Categories
            .Where(cate => cate.CateName.Contains(cateName))
            .Select(cate => new CategoryAndProduct
            {
                CategoryId = cate.Id,
                CategoryName = cate.CateName,
                ProductList = _db.Goods
                    .Where(goods => cate.Id == goods.CateId)
                    .Select(goods => new SimpleProductUM
                    {
                        GoodsId = goods.Id,
                        Name = goods.Name,
                    }).ToList()
            }).ToList();
            return categoryAndProducts;
        }

    }
}
